﻿using System;
using System.Drawing;
using System.Windows.Forms;
using MediaPlayer;
using System.IO;


namespace SimpleMediaPlayer
{
    public partial class Main : Form
    {
        private FormWindowState oldWindowState;
        private Rectangle oldBounds;

        public Main()
        {
            InitializeComponent();
        }

        private void Main_Load(object sender, EventArgs e)
        {
            player.Renderer = Program.Settings.Renderer;
            player.Speed = Program.Settings.Speed;
            player.DisableScreensaver = Program.Settings.DisableScreensaver;
            player.AspectRatio = AspectRatio.AROriginal;
            ChangeVolume(Program.Settings.Volume, true);

            player.StateChanged += new Player.StateChangedHandler(player_StateChanged);
            player.MouseMove += new Player.MouseMoveHandler(player_MouseMove);
            player.DoubleClick += new Player.DoubleClickHandler(player_DoubleClick);
            player.RightClick += new Player.RightClickHandler(player_RightClick);
            player.MouseScroll += new Player.MouseScrollHandler(player_MouseScroll);

            string[] args = Environment.GetCommandLineArgs();

            if (args.Length > 1)
            {
                OpenFile(args[1]);
            }
        }

        #region Event Handlers

        void player_StateChanged(Player p, PlayState oldState, PlayState newState)
        {
            ShowOverlay(newState.ToString());
        }

        private int x = 0;
        private int y = 0;
        private DateTime LastMouseMove;
        private bool CursorHidden = false;

        private void player_MouseMove(Player p, MouseEventArgs e)
        {
            if (!player.ClientRectangle.Contains(player.PointToClient(Control.MousePosition)) || panelControls.ClientRectangle.Contains(panelControls.PointToClient(Control.MousePosition))) return;

            if ((e.X != x) || (e.Y != y)) // Mouse location changed
            {
                x = e.X;
                y = e.Y;

                LastMouseMove = DateTime.Now;

                if (CursorHidden)
                {
                    Cursor.Show();
                    CursorHidden = false;
                }


                if (this.FormBorderStyle == FormBorderStyle.None) // Fullscreen
                {
                    if (!panelControls.Visible)
                    {
                        panelControls.Show();
                    }
                }
            }
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.CheckFileExists = true;
            ofd.AddExtension = true;
            ofd.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyComputer);
            ofd.Multiselect = false;

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                Stop();
                OpenFile(ofd.FileName);
            }
        }

        void player_MouseScroll(Player p, MouseEventArgs e)
        {
            if (e.Delta > 0)
            {
                ChangeVolume(+5);
            }
            else
            {
                ChangeVolume(-5);
            }
        }

        void player_RightClick(Player p, EventArgs e)
        {
            contextMenuStrip.Show(Cursor.Position);
        }

        void player_DoubleClick(Player p, EventArgs e)
        {
            ToggleFullscreen();
        }

        void player_Draw(Player p, EventArgs e)
        {
            toolStripStatusLabelPosition.Text = getPlaybackPositionString(player.Position, player.Length.Value);
        }

        private void timer_Tick(object sender, EventArgs e)
        {
            toolStripStatusLabelPosition.Text = getPlaybackPositionString(player.Position, player.Length.Value);

            if ((int)player.Position >= trackBarPosition.Minimum && (int)player.Position <= trackBarPosition.Maximum)
            {
                trackBarPosition.Value = (int)player.Position;
            }
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            About about = new About();
            about.ShowDialog();
        }

        private void player_DoubleClick(object sender, EventArgs e)
        {
            ToggleFullscreen();
        }

        private void buttonPause_Click(object sender, EventArgs e)
        {
            if (player.State == PlayState.Playing)
            {
                Pause();
            }
            else if (player.State != PlayState.NoFile)
            {
                Play();
            }
        }

        private void buttonStop_Click(object sender, EventArgs e)
        {
            Stop();
        }

        private void buttonFullscreen_Click(object sender, EventArgs e)
        {
            ToggleFullscreen();
        }

        private void buttonPlaybackSlower_Click(object sender, EventArgs e)
        {
            player.Speed -= 0.1;
        }

        private void buttonPlaybackFaster_Click(object sender, EventArgs e)
        {
            player.Speed += 0.1;
        }

        private void trackBarPosition_Scroll(object sender, EventArgs e)
        {
            player.Position = trackBarPosition.Value;
        }

        private void buttonMute_Click(object sender, EventArgs e)
        {
            ToggleMute();
        }

        private void trackBarVolume_Scroll(object sender, EventArgs e)
        {
            ChangeVolume(trackBarVolume.Value, true);
        }

        private void increaseVolumeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ChangeVolume(+10);
        }

        private void decreaseVolumeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ChangeVolume(-10);
        }

        private void muteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ToggleMute();
        }

        private void timerMouse_Tick(object sender, EventArgs e)
        {
            if (menuOpen) return;
            if (!player.ClientRectangle.Contains(player.PointToClient(Control.MousePosition)) || panelControls.ClientRectangle.Contains(panelControls.PointToClient(Control.MousePosition))) return;

            TimeSpan elaped = DateTime.Now - LastMouseMove;

            if (Program.Settings.HideFullscreenControls && this.FormBorderStyle == FormBorderStyle.None && elaped >= TimeSpan.FromMilliseconds(Program.Settings.FullscreenControlsTimeout) && panelControls.Visible)
            {
                panelControls.Hide();
            }

            if (Program.Settings.HideIdleCursor && !CursorHidden && (player.State == PlayState.Paused || player.State == PlayState.Playing) && elaped >= TimeSpan.FromMilliseconds(Program.Settings.IdleCursorTimeout))
            {
                Cursor.Hide();
                CursorHidden = true;
            }
        }

        private void Main_Resize(object sender, EventArgs e)
        {
            labelOverlay.Location = new Point((this.Width - labelOverlay.Width) / 2, labelOverlay.Location.Y);
        }

        private void timerOverlay_Tick(object sender, EventArgs e)
        {
            timerOverlay.Stop();

            labelOverlay.Hide();
        }

        private void Main_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.Copy;
        }

        private void Main_DragDrop(object sender, DragEventArgs e)
        {
            string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);

            if (System.IO.File.Exists(files[0]))
            {
                Stop();
                OpenFile(files[0]);
            }
        }

        private void Main_FormClosing(object sender, FormClosingEventArgs e)
        {
            player.Close();
        }

        private void quarterToolStripMenuItem_Click(object sender, EventArgs e)
        {
            player.ScaleVideo(0.25);
        }

        private void halfToolStripMenuItem_Click(object sender, EventArgs e)
        {
            player.ScaleVideo(0.5);
        }

        private void originalToolStripMenuItem_Click(object sender, EventArgs e)
        {
            player.ScaleVideo(1);
        }

        private void doubleToolStripMenuItem_Click(object sender, EventArgs e)
        {
            player.ScaleVideo(2);
        }

        private void toolStripStatusLabelPosition_Click(object sender, EventArgs e)
        {
            if (player.State == PlayState.NoFile) return;

            GoToTime time = new GoToTime(player.Position, player.Length.Value);
            time.ShowDialog();

            if (time.Position != -1)
            {
                player.Position = time.Position;
            }
        }

        #endregion

        private void OpenFile(string file)
        {
            if (player.LoadFile(file))
            {
                Play();
            }
            else
            {
                MessageBox.Show("Invalid media file", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }

        private void Play()
        {
            trackBarPosition.Maximum = (int)player.Length.Value.TotalSeconds;
            toolStripStatusLabelPosition.Text = getPlaybackPositionString(player.Position, player.Length.Value);
            toolStripStatusLabelStatus.Text = Path.GetFileName(player.File);

            if (player.Type == MediaType.Audio)
            {
                string a = Path.Combine(Path.GetDirectoryName(player.File), "folder.jpg");

                if (File.Exists(a))
                {
                    player.BackColor = Color.Black;
                    player.BackgroundImageLayout = ImageLayout.Zoom;
                    player.BackgroundImage = new Bitmap(a);
                }
            }

            player.Play();
            buttonPause.Image = global::SimpleMediaPlayer.Properties.Resources.pause;

            timer.Start();
        }

        private void Pause()
        {
            player.Pause();
            buttonPause.Image = global::SimpleMediaPlayer.Properties.Resources.play;
        }

        private void Stop()
        {
            timer.Stop();

            player.Stop();

            player.BackColor = Color.Black;
            player.BackgroundImageLayout = ImageLayout.Center;
            player.BackgroundImage = global::SimpleMediaPlayer.Properties.Resources.icon;

            buttonPause.Image = global::SimpleMediaPlayer.Properties.Resources.play;

            trackBarPosition.Maximum = 0;
            toolStripStatusLabelPosition.Text = "--:--:--/--:--:--";
            toolStripStatusLabelStatus.Text = "Ready";
        }

        private void ShowOverlay(string text)
        {
            if (!Program.Settings.ShowOSD) return;

            labelOverlay.Text = text;
            labelOverlay.Location = new Point((this.Width - labelOverlay.Width) / 2, labelOverlay.Location.Y);
            labelOverlay.Show();
            timerOverlay.Start();
        }

        private void ToggleMute()
        {
            player.Mute();

            muteToolStripMenuItem.Checked = player.Muted;

            if (player.Muted)
            {
                buttonMute.Image = global::SimpleMediaPlayer.Properties.Resources.volume_mute;
            }
            else
            {
                buttonMute.Image = global::SimpleMediaPlayer.Properties.Resources.volume_max;
            }
        }

        private void ChangeVolume(int adjustment, bool set = false)
        {
            if (set)
            {
                player.Volume = adjustment;
            }
            else
            {
                player.Volume += adjustment;
            }

            this.trackBarVolume.Value = player.Volume;
        }

        private void ToggleFullscreen()
        {
            if (this.FormBorderStyle == FormBorderStyle.Sizable)
            {
                oldWindowState = this.WindowState;
                oldBounds = this.Bounds;

                this.FormBorderStyle = FormBorderStyle.None;
                this.WindowState = FormWindowState.Normal;
                this.Bounds = Screen.FromControl(this).Bounds;
                this.menuStrip.Hide();
                this.statusStrip.Hide();

                this.panelControls.Dock = DockStyle.None;
                this.panelControls.Location = new Point(0, Screen.FromControl(this).Bounds.Height - this.panelControls.Height);
                this.panelControls.Width = Screen.FromControl(this).Bounds.Width;
                this.panelControls.BringToFront();
            }
            else
            {
                this.FormBorderStyle = FormBorderStyle.Sizable;
                this.WindowState = oldWindowState;
                this.Bounds = oldBounds;
                this.menuStrip.Show();
                this.statusStrip.Show();

                this.panelControls.Dock = DockStyle.Bottom;
                this.panelControls.SendToBack();
                this.panelControls.Show();
                this.panelControls.BackColor = Control.DefaultBackColor;
            }
        }

        private string getPlaybackPositionString(double current, TimeSpan total)
        {
            string timeTotal = "";
            string timeCurrent = "";
            int timeCurrentHours = (int)((current / 60) / 60);
            int timeCurrentMinutes = (int)((current / 60) % 60);
            int timeCurrentSeconds = (int)(current % 60);
            if (total.Hours > 0)
            {
                timeCurrent = timeCurrentHours.ToString().PadLeft(2, '0') + ":";
                timeTotal = total.Hours.ToString().PadLeft(2, '0') + ":";
            }
            timeCurrent += timeCurrentMinutes.ToString().PadLeft(2, '0') + ":";
            timeTotal += total.Minutes.ToString().PadLeft(2, '0') + ":";
            timeCurrent += timeCurrentSeconds.ToString().PadLeft(2, '0');
            timeTotal += total.Seconds.ToString().PadLeft(2, '0');

            return timeCurrent + "/" + timeTotal;
        }

        private bool menuOpen = false;
        private void menuStrip_MenuActivate(object sender, EventArgs e)
        {
            menuOpen = true;
        }

        private void menuStrip_MenuDeactivate(object sender, EventArgs e)
        {
            menuOpen = false;
        }

        private void contextMenuStrip_Opening(object sender, System.ComponentModel.CancelEventArgs e)
        {
            menuOpen = true;
        }

        private void contextMenuStrip_Closing(object sender, ToolStripDropDownClosingEventArgs e)
        {
            menuOpen = false;
        }

        #region Aspect Ratio Context Menu

        private void defaultToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ChangeAspectRatio(AspectRatio.AROriginal, sender);
        }

        private void ar1_1ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ChangeAspectRatio(AspectRatio.AR1_1, sender);
        }

        private void ar4_3ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ChangeAspectRatio(AspectRatio.AR4_3, sender);
        }

        private void ar16_9ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ChangeAspectRatio(AspectRatio.AR16_9, sender);
        }

        private void ar16_10ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ChangeAspectRatio(AspectRatio.AR16_10, sender);
        }

        private void ar221_1ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ChangeAspectRatio(AspectRatio.AR221_1, sender);
        }

        private void ar235_1ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ChangeAspectRatio(AspectRatio.AR235_1, sender);
        }

        private void ar239_1ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ChangeAspectRatio(AspectRatio.AR239_1, sender);
        }

        private void ar5_4ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ChangeAspectRatio(AspectRatio.AR5_4, sender);
        }

        #endregion

        private void ChangeAspectRatio(double ar, object sender)
        {
            this.player.AspectRatio = ar;

            foreach (ToolStripMenuItem item in aspectRatioToolStripMenuItem.DropDownItems)
            {
                item.Checked = false;
            }

            ((ToolStripMenuItem)sender).Checked = true;
        }

        private void scaleToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.player.Stretch = scaleToolStripMenuItem.Checked;
        }

        private void mediaInfomationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MediaInfomation form = new MediaInfomation(this.player);
            form.ShowDialog();
        }
    }
}
